﻿//---------------------------------------------------------------------
// <copyright file="QueryTreeInfo.cs" company="Microsoft">
//      Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
// </copyright>
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace System.Data.Test.Astoria.Expressions
{
    /// <summary>
    /// Contains the query node tree info to verify, the expression tree that is generated by the query node tree
    /// Also contains the Verification class info.
    /// This class builds the next query node tree and also calls the verification on the generated expression tree
    /// </summary>
   
    public class QueryTreeInfo
    {
        // service root URI
        private string m_svcRootURI;
        public string svcRootURI 
        {
            get { return m_svcRootURI; }
            set { m_svcRootURI = value; } 
        }

        // target URI - will be used later if the model has to build up to a given target URI
        private string m_targetURI;
        public string targetURI
        {
            get { return m_targetURI; }
            set { m_targetURI = value; } 
        }

        // expression tree of the svc root URI
        private string m_rootTree;
        public string rootTree
        {
            get { return m_rootTree; }
            set { m_rootTree = value; }
        }

        // tree from previous iteration - will be used when we build queries of multi levels
        private string m_prevTree;
        public string prevTree
        {
            get { return m_prevTree; }
            set { m_prevTree = value; }
        }

        // expression tree of current query under test
        private string m_currentTree;
        public string currentTree
        {
            get { return m_currentTree; }
            set { m_currentTree = value; }
        }

        private XmlDocument m_currentTreeXml;
        public XmlDocument currentTreeXml
        {
            get { return m_currentTreeXml; }
            set { m_currentTreeXml = value; }
        }

        // diff between current and prev tree
        private string m_diffTree;
        public string diffTree
        {
            get { return m_diffTree; }
            set { m_diffTree = value; }
        }

        // root query tree 
        private QueryNode m_rootQueryNodeTree;
        public QueryNode rootQueryNodeTree
        {
            get { return m_rootQueryNodeTree; }
            set { m_rootQueryNodeTree = value; }
        }

        // input query tree thats being tested
        private QueryNode m_queryNodeTree;
        public QueryNode queryNodeTree
        {
            get { return m_queryNodeTree; }
            set { m_queryNodeTree = value; }
        }

        // Query component - tells what component has been added to the input test query tree and verification class to use
        private QueryComponent m_queryComponent;
        public QueryComponent queryComponent
        {
            get { return m_queryComponent; }
            set { m_queryComponent = value; }
        }

        // Resource container - this is the root on top of which query components are added
        private ResourceContainer m_resourceContainer;
        public ResourceContainer resourceContainer
        {
            get { return m_resourceContainer; }
            set { m_resourceContainer = value; }
        }
        
        // workspace
        private Workspace m_wkspc;
        public Workspace wkspc
        {
            get { return m_wkspc; }
            set { m_wkspc = value; }
        }
        
        // Verification class
        private AbstractExprTreePattern pattern;

        public QueryTreeInfo(Workspace wkspc, string rootTree, string targetURI) 
        {
            this.targetURI = targetURI;
            this.wkspc = wkspc;
            this.rootTree = rootTree;
            this.svcRootURI = wkspc.ServiceUri;
        }

        // Generate the next random query to test
        public void Next()
        {
            // Choose a random Query component to test
            this.queryComponent = Enum.GetValues(typeof(QueryComponent)).Cast<QueryComponent>().Choose();
            AstoriaTestLog.WriteLine("Testing.... " + this.queryComponent.ToString());

            // Idenity the queryComponents corresponding verification class
            ConcretePatternDictionary patternDictionary = new ConcretePatternDictionary();
            this.pattern = patternDictionary.GetPattern(this.queryComponent);

            // Build the actual query tree for the queryComponent
            this.pattern.Build(this);
        }

        // Call the compare method of corresponding pattern class to verify the expr tree
        public void Verify()
        {
            // NOTE: The difftree assignment will change later once we go into multi level Query components
            this.diffTree = this.currentTree;

            //Do the comparison on the diff ET 
            bool result = this.pattern.Compare(this);
            if (result)
            {
                //Only if succeeded, replace the prev tree with current, else preserve since it will be needed for debugging.
                this.prevTree = this.currentTree;
            }
            else
            {
                AstoriaTestLog.FailAndContinue(new Exception("Tree comparison failed"));
            }
            
        }

    }
}
